package com.maxmlr.framework.aop;

import com.sun.istack.internal.NotNull;
import lombok.Setter;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

/**
 * @ClassName AopProxy
 * @Description TODO
 * @Author maxiao
 * @Date 2020/3/13 下午5:02
 * @Version V1.0
 */
@Setter
public class AopProxy implements InvocationHandler {

    private AopConfig config;
    private Object target;

    public Object getProxy(@NotNull Object instance) {
        this.target = instance;
        Class<?> clazz = instance.getClass();
        return Proxy.newProxyInstance(clazz.getClassLoader(), clazz.getInterfaces(), this);
    }

    /**
     * 执行代理方法
     *
     * @param proxy
     * @param method
     * @param args
     * @return
     * @throws Throwable
     */
    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        //拿到原生方法
        Method m = this.target.getClass().getMethod(method.getName(), method.getParameterTypes());

        boolean contains = config.contains(m);

        if (contains) {
            Aspect aspect = config.get(m);
            //执行第一个切面方法
            aspect.getPoints()[0].invoke(aspect.getAspect());
        }

        //执行原生方法
        Object invoke = method.invoke(target, args);

        if (contains) {
            Aspect aspect = config.get(m);
            //执行第二个切面方法
            aspect.getPoints()[1].invoke(aspect.getAspect());
        }

        return invoke;
    }
}
